package yunjiao.javatutorials.guava.concurrent.transform.assembly;

import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;

import java.util.UUID;
import java.util.concurrent.Executors;

/**
 * 图片处理服务
 *
 * @author yangyunjiao
 */
public class ImageProcessingService {
    private final ListeningExecutorService executor =
            MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(8));

    /**
     * 图片处理流水线：下载 -> 调整大小 -> 应用滤镜 -> 上传到CDN
     */
    public ListenableFuture<ProcessedImage> processImageAsync(String imageUrl) {
        System.out.println(">>>图片处理流水线：下载 -> 调整大小 -> 应用滤镜 -> 上传到CDN");
        // 1. 下载图片
        ListenableFuture<ImageData> downloadFuture = downloadImageAsync(imageUrl);

        // 2. 调整大小
        ListenableFuture<ImageData> resizedFuture = Futures.transform(
                downloadFuture,
                image -> resizeImage(image, 800, 600),
                executor
        );

        // 3. 应用滤镜（可能有多种滤镜选择）
        ListenableFuture<ImageData> filteredFuture = Futures.transform(
                resizedFuture,
                image -> applyFilter(image, "sepia"),
                executor
        );

        // 4. 压缩图片
        ListenableFuture<ImageData> compressedFuture = Futures.transform(
                filteredFuture,
                this::compressImage,
                executor
        );

        // 5. 上传到CDN并返回结果
        return Futures.transformAsync(
                compressedFuture,
                this::uploadToCdnAsync,
                executor
        );
    }

    /**
     * 带错误恢复的图片处理
     */
    public ListenableFuture<ProcessedImage> processImageWithFallbackAsync(String imageUrl) {
        ListenableFuture<ProcessedImage> mainProcess = processImageAsync(imageUrl);

        // 如果主处理失败，使用降级方案
        return Futures.catching(
                mainProcess,
                Exception.class,
                exception -> {
                    System.out.println("图片处理失败，使用降级方案" + exception.getMessage());
                    return createFallbackImage(imageUrl);
                },
                executor
        );
    }

    private ListenableFuture<ImageData> downloadImageAsync(String imageUrl) {
        System.out.println("downloadImageAsync");
        return executor.submit(() -> {
            // 模拟网络下载
            Thread.sleep(200);
            return new ImageData(imageUrl, new byte[1024], "JPEG");
        });
    }

    private ImageData resizeImage(ImageData original, int width, int height) {
        System.out.println("模拟图片 resize 操作");
        return new ImageData(original.sourceUrl(), original.data(), original.format());
    }

    private ImageData applyFilter(ImageData image, String filterType) {
        System.out.println("模拟滤镜应用");
        return new ImageData(image.sourceUrl(), image.data(), image.format());
    }

    private ImageData compressImage(ImageData image) {
        System.out.println("模拟图片压缩");
        return new ImageData(image.sourceUrl(), image.data(), image.format());
    }

    private ListenableFuture<ProcessedImage> uploadToCdnAsync(ImageData image) {
        System.out.println("uploadToCdnAsync");
        return executor.submit(() -> {
            // 模拟CDN上传
            Thread.sleep(100);
            String cdnUrl = "https://cdn.example.com/images/" +
                    UUID.randomUUID() + "." + image.format().toLowerCase();
            return new ProcessedImage(image.sourceUrl(), cdnUrl, image.data().length);
        });
    }

    private ProcessedImage createFallbackImage(String imageUrl) {
        System.out.println("createFallbackImage");
        return new ProcessedImage(imageUrl, "https://cdn.example.com/fallback.jpg", 0);
    }


}
